/**
 * Copyright (C) 2021-2022 maminjie <canpool@163.com>
 * SPDX-License-Identifier: LGPL-2.1
 * Powered by Qt-Advanced-Docking-System
**/

#include "dockoverlay.h"

#include "dockpannel.h"
#include "docktitlebar.h"

#include <QCursor>
#include <QGridLayout>
#include <QIcon>
#include <QLabel>
#include <QMap>
#include <QMoveEvent>
#include <QPaintEvent>
#include <QPainter>
#include <QPointer>
#include <QResizeEvent>
#include <QWindow>
#include <QtGlobal>

#include <iostream>

QADS_BEGIN_NAMESPACE

class DockOverlayPrivate
{
public:
    DockOverlayPrivate(DockOverlay *parent);

public:
    DockOverlay *q;
    DockWidgetAreas m_allowedAreas = InvalidDockWidgetArea;
    DockOverlayCross *m_cross = nullptr;
    QPointer<QWidget> m_targetWidget;
    DockWidgetArea m_lastLocation = InvalidDockWidgetArea;
    bool m_dropPreviewEnabled = true;
    DockOverlay::Mode m_mode = DockOverlay::ModePannelOverlay;
    QRect m_dropAreaRect;
};

DockOverlayPrivate::DockOverlayPrivate(DockOverlay *parent)
    : q(parent)
{}


DockOverlay::DockOverlay(QWidget *parent, Mode mode)
    : QWidget(parent)
    , d(new DockOverlayPrivate(this))
{
    d->m_mode = mode;
    d->m_cross = new DockOverlayCross(this);
#if defined(Q_OS_LINUX)
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
                   | Qt::X11BypassWindowManagerHint);
#else
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
#endif
    setWindowOpacity(1);
    setWindowTitle("DockOverlay");
    setAttribute(Qt::WA_NoSystemBackground);
    setAttribute(Qt::WA_TranslucentBackground);
    d->m_cross->setVisible(false);
    setVisible(false);
}

DockOverlay::~DockOverlay()
{
    delete d;
}

void DockOverlay::setAllowedAreas(DockWidgetAreas areas)
{
    if (areas == d->m_allowedAreas) {
        return;
    }

    d->m_allowedAreas = areas;
    d->m_cross->reset();
}

DockWidgetAreas DockOverlay::allowedAreas() const
{
    return d->m_allowedAreas;
}

DockWidgetArea DockOverlay::dropAreaUnderCursor() const
{
    DockWidgetArea result = d->m_cross->cursorLocation();
    if (result != InvalidDockWidgetArea) {
        return result;
    }

    DockPannel *pannel = qobject_cast<DockPannel *>(d->m_targetWidget.data());
    if (!pannel) {
        return result;
    }

    if (pannel->allowedAreas().testFlag(CenterDockWidgetArea)
            && !pannel->titleBar()->isHidden()
            && pannel->titleBarGeometry().contains(pannel->mapFromGlobal(QCursor::pos()))) {
        return CenterDockWidgetArea;
    }

    return result;
}

DockWidgetArea DockOverlay::visibleDropAreaUnderCursor() const
{
    if (isHidden() || !d->m_dropPreviewEnabled) {
        return InvalidDockWidgetArea;
    } else {
        return dropAreaUnderCursor();
    }
}

DockWidgetArea DockOverlay::showOverlay(QWidget *target)
{
    if (d->m_targetWidget == target) {
        // Hint: We could update geometry of overlay here.
        DockWidgetArea area = dropAreaUnderCursor();
        if (area != d->m_lastLocation) {
            repaint();
            d->m_lastLocation = area;
        }
        return area;
    }

    d->m_targetWidget = target;
    d->m_lastLocation = InvalidDockWidgetArea;
    // Move it over the target.
    hide();
    resize(target->size());
    QPoint topLeft = target->mapToGlobal(target->rect().topLeft());
    move(topLeft);
    show();
    d->m_cross->updatePosition();
    d->m_cross->updateOverlayIcons();
    return dropAreaUnderCursor();
}

void DockOverlay::hideOverlay()
{
    hide();
    d->m_targetWidget.clear();
    d->m_lastLocation = InvalidDockWidgetArea;
    d->m_dropAreaRect = QRect();
}

void DockOverlay::enableDropPreview(bool enable)
{
    d->m_dropPreviewEnabled = enable;
    update();
}

bool DockOverlay::dropPreviewEnabled() const
{
    return d->m_dropPreviewEnabled;
}

QRect DockOverlay::dropOverlayRect() const
{
    return d->m_dropAreaRect;
}

bool DockOverlay::event(QEvent *event)
{
    bool result = QWidget::event(event);

    if (event->type() == QEvent::Polish) {
        d->m_cross->setupOverlayCross(d->m_mode);
    }

    return result;
}

void DockOverlay::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    // Draw rect based on location
    if (!d->m_dropPreviewEnabled) {
        d->m_dropAreaRect = QRect();
        return;
    }

    QRect rectangle = rect();
    const DockWidgetArea area = dropAreaUnderCursor();
    double factor = (d->m_mode == DockOverlay::ModeContainerOverlay) ? 3 : 2;

    switch (area) {
    case TopDockWidgetArea:
        rectangle.setHeight(static_cast<int>(rectangle.height() / factor));
        break;
    case RightDockWidgetArea:
        rectangle.setX(static_cast<int>(rectangle.width() * (1 - 1 / factor)));
        break;
    case BottomDockWidgetArea:
        rectangle.setY(static_cast<int>(rectangle.height() * (1 - 1 / factor)));
        break;
    case LeftDockWidgetArea:
        rectangle.setWidth(static_cast<int>(rectangle.width() / factor));
        break;
    case CenterDockWidgetArea:
        rectangle = rect();
        break;
    default:
        return;
    }

    QPainter painter(this);
    QColor color = palette().color(QPalette::Active, QPalette::Highlight);
    QPen pen = painter.pen();
    pen.setColor(color.darker(120));
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(1);
    pen.setCosmetic(true);
    painter.setPen(pen);
    color = color.lighter(130);
    color.setAlpha(64);
    painter.setBrush(color);
    painter.drawRect(rectangle.adjusted(0, 0, -1, -1));
    d->m_dropAreaRect = rectangle;
}

void DockOverlay::showEvent(QShowEvent *event)
{
    d->m_cross->show();
    QWidget::showEvent(event);
}

void DockOverlay::hideEvent(QHideEvent *event)
{
    d->m_cross->hide();
    QWidget::hideEvent(event);
}

static Qt::Alignment areaAlignment(const DockWidgetArea area)
{
    switch (area) {
    case TopDockWidgetArea:
        return Qt::AlignHCenter | Qt::AlignBottom;
    case RightDockWidgetArea:
        return Qt::AlignLeft | Qt::AlignVCenter;
    case BottomDockWidgetArea:
        return Qt::AlignHCenter | Qt::AlignTop;
    case LeftDockWidgetArea:
        return Qt::AlignRight | Qt::AlignVCenter;
    case CenterDockWidgetArea:
        return Qt::AlignCenter;
    default:
        return Qt::AlignCenter;
    }
}

/**
 * Private data of DockOverlayCross class
 */
class DockOverlayCrossPrivate
{
public:
    DockOverlayCrossPrivate(DockOverlayCross *parent);

    QPoint areaGridPosition(const DockWidgetArea area);

    QColor defaultIconColor(DockOverlayCross::ColorRole role);
    QColor iconColor(DockOverlayCross::ColorRole role);

    qreal dropIndicatiorWidth(QLabel *label) const;
    QPixmap createHighDpiDropIndicatorPixmap(const QSizeF &size, DockWidgetArea area, DockOverlay::Mode mode);
    QWidget *createDropIndicatorWidget(DockWidgetArea area, DockOverlay::Mode mode);
    void updateDropIndicatorIcon(QWidget *dropIndicatorWidget);

public:
    DockOverlayCross *q;
    DockOverlay::Mode m_mode = DockOverlay::ModePannelOverlay;
    DockOverlay *m_dockOverlay = nullptr;
    QHash<DockWidgetArea, QWidget *> m_dropIndicatorWidgets;
    QGridLayout *m_gridLayout = nullptr;
    QColor m_iconColors[DockOverlayCross::COLOR_ROLE_CNT];
    bool m_updateRequired = false;
    double m_lastDevicePixelRatio = 0.1;
}; // class DockOverlayCrossPrivate


// DockOverlayCrossPrivate
DockOverlayCrossPrivate::DockOverlayCrossPrivate(DockOverlayCross *parent)
    : q(parent)
{}

/**
 * @brief DockOverlayCrossPrivate::areaGridPosition
 * @param area
 * @return point(row, column)
 */
QPoint DockOverlayCrossPrivate::areaGridPosition(const DockWidgetArea area)
{
    if (m_mode == DockOverlay::ModePannelOverlay) {
        switch (area) {
        case TopDockWidgetArea:
            return QPoint(1, 2);
        case RightDockWidgetArea:
            return QPoint(2, 3);
        case BottomDockWidgetArea:
            return QPoint(3, 2);
        case LeftDockWidgetArea:
            return QPoint(2, 1);
        case CenterDockWidgetArea:
            return QPoint(2, 2);
        default:
            return QPoint();
        }
    } else {
        switch (area) {
        case TopDockWidgetArea:
            return QPoint(0, 2);
        case RightDockWidgetArea:
            return QPoint(2, 4);
        case BottomDockWidgetArea:
            return QPoint(4, 2);
        case LeftDockWidgetArea:
            return QPoint(2, 0);
        case CenterDockWidgetArea:
            return QPoint(2, 2);
        default:
            return QPoint();
        }
    }
}

QColor DockOverlayCrossPrivate::defaultIconColor(DockOverlayCross::ColorRole role)
{
    QPalette palette = q->palette();

    switch (role) {
    case DockOverlayCross::Border:
        return palette.color(QPalette::Active, QPalette::Highlight);
    case DockOverlayCross::Window:
        return palette.color(QPalette::Active, QPalette::Base);
    case DockOverlayCross::Overlay: {
        QColor color = palette.color(QPalette::Active, QPalette::Highlight);
        color.setAlpha(64);
        return color;
    }
    case DockOverlayCross::Arrow:
        return palette.color(QPalette::Active, QPalette::Base);
    case DockOverlayCross::Shadow:
        return QColor(0, 0, 0, 64);
    }
    return QColor();
}

QColor DockOverlayCrossPrivate::iconColor(DockOverlayCross::ColorRole role)
{
    QColor color = m_iconColors[role];

    if (!color.isValid()) {
        color = defaultIconColor(role);
        m_iconColors[role] = color;
    }

    return color;
}

qreal DockOverlayCrossPrivate::dropIndicatiorWidth(QLabel *label) const
{
#if defined(Q_OS_LINUX)
    return 40;
#else
    return static_cast<qreal>(label->fontMetrics().height()) * 3.f;
#endif
}

QPixmap DockOverlayCrossPrivate::createHighDpiDropIndicatorPixmap(const QSizeF &size, DockWidgetArea area,
                                                                  DockOverlay::Mode mode)
{
    const QColor borderColor = iconColor(DockOverlayCross::Border);
    const QColor backgroundColor = iconColor(DockOverlayCross::Window);
    const double devicePixelRatio = q->window()->devicePixelRatioF();
    const QSizeF pixmapSize = size * devicePixelRatio;
    QPixmap pixmap(pixmapSize.toSize());
    pixmap.fill(QColor(0, 0, 0, 0));
    QPainter painter(&pixmap);
    QPen pen = painter.pen();
    QRectF shadowRect(pixmap.rect());
    QRectF baseRect;
    baseRect.setSize(shadowRect.size() * 0.7);
    baseRect.moveCenter(shadowRect.center());
    // Fill
    QColor shadowColor = iconColor(DockOverlayCross::Shadow);
    if (shadowColor.alpha() == 255) {
        shadowColor.setAlpha(64);
    }
    painter.fillRect(shadowRect, shadowColor);
    // Drop area rect.
    painter.save();
    QRectF areaRect;
    QRectF nonAreaRect;
    QLineF areaLine;

    switch (area) {
    case TopDockWidgetArea:
        areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * 0.5);
        nonAreaRect = QRectF(baseRect.x(), shadowRect.height() * 0.5, baseRect.width(), baseRect.height() * 0.5);
        areaLine = QLineF(areaRect.bottomLeft(), areaRect.bottomRight());
        break;
    case RightDockWidgetArea:
        areaRect = QRectF(shadowRect.width() * 0.5, baseRect.y(), baseRect.width() * 0.5, baseRect.height());
        nonAreaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * 0.5, baseRect.height());
        areaLine = QLineF(areaRect.topLeft(), areaRect.bottomLeft());
        break;
    case BottomDockWidgetArea:
        areaRect = QRectF(baseRect.x(), shadowRect.height() * 0.5, baseRect.width(), baseRect.height() * 0.5);
        nonAreaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width(), baseRect.height() * 0.5);
        areaLine = QLineF(areaRect.topLeft(), areaRect.topRight());
        break;
    case LeftDockWidgetArea:
        areaRect = QRectF(baseRect.x(), baseRect.y(), baseRect.width() * 0.5, baseRect.height());
        nonAreaRect = QRectF(shadowRect.width() * 0.5, baseRect.y(),  baseRect.width() * 0.5,  baseRect.height());
        areaLine = QLineF(areaRect.topRight(), areaRect.bottomRight());
        break;
    default:
        break;
    }

    const QSizeF baseSize = baseRect.size();

    if (mode == DockOverlay::ModeContainerOverlay && area != CenterDockWidgetArea) {
        baseRect = areaRect;
    }

    painter.fillRect(baseRect, backgroundColor);

    if (areaRect.isValid()) {
        QColor color = iconColor(DockOverlayCross::Overlay);
        if (color.alpha() == 255) {
            color.setAlpha(64);
        }
        painter.setBrush(color);
        painter.setPen(Qt::NoPen);
        painter.drawRect(areaRect);
        pen = painter.pen();
        pen.setWidth(1);
        pen.setColor(borderColor);
        pen.setStyle(Qt::DashLine);
        painter.setPen(pen);
        painter.drawLine(areaLine);
    }

    painter.restore();
    painter.save();
    // Draw outer border
    pen = painter.pen();
    pen.setColor(borderColor);
    pen.setWidth(1);
    painter.setBrush(Qt::NoBrush);
    painter.setPen(pen);
    painter.drawRect(baseRect);
    // draw window title bar
    painter.setBrush(borderColor);
    const QRectF frameRect(baseRect.topLeft(), QSizeF(baseRect.width(), baseSize.height() / 10));
    painter.drawRect(frameRect);
    painter.restore();

    // Draw arrow for outer container drop indicators
    if (mode == DockOverlay::ModeContainerOverlay && area != CenterDockWidgetArea) {
        QRectF arrowRect;
        arrowRect.setSize(baseSize);
        arrowRect.setWidth(arrowRect.width() / 4.6);
        arrowRect.setHeight(arrowRect.height() / 2);
        arrowRect.moveCenter(QPointF(0, 0));
        QPolygonF arrow;
        arrow << arrowRect.topLeft() << QPointF(arrowRect.right(), arrowRect.center().y())
              << arrowRect.bottomLeft();
        painter.setPen(Qt::NoPen);
        painter.setBrush(iconColor(DockOverlayCross::Arrow));
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.translate(nonAreaRect.center().x(), nonAreaRect.center().y());

        switch (area) {
        case TopDockWidgetArea:
            painter.rotate(-90);
            break;
        case RightDockWidgetArea:
            break;
        case BottomDockWidgetArea:
            painter.rotate(90);
            break;
        case LeftDockWidgetArea:
            painter.rotate(180);
            break;
        default:
            break;
        }
        painter.drawPolygon(arrow);
    }

    pixmap.setDevicePixelRatio(devicePixelRatio);
    return pixmap;
}

QWidget *DockOverlayCrossPrivate::createDropIndicatorWidget(DockWidgetArea area, DockOverlay::Mode mode)
{
    QLabel *label = new QLabel();
    label->setObjectName("DockWidgetAreaLabel");
    const qreal metric = dropIndicatiorWidth(label);
    const QSizeF size(metric, metric);
    label->setPixmap(createHighDpiDropIndicatorPixmap(size, area, mode));
    label->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
    label->setAttribute(Qt::WA_TranslucentBackground);
    label->setProperty("dockWidgetArea", area);
    return label;
}

void DockOverlayCrossPrivate::updateDropIndicatorIcon(QWidget *dropIndicatorWidget)
{
    QLabel *label = qobject_cast<QLabel *>(dropIndicatorWidget);
    const qreal metric = dropIndicatiorWidth(label);
    const QSizeF size(metric, metric);
    DockWidgetArea area = static_cast<DockWidgetArea>(label->property("dockWidgetArea").toInt());
    label->setPixmap(createHighDpiDropIndicatorPixmap(size, area, m_mode));
}

DockOverlayCross::DockOverlayCross(DockOverlay *overlay)
    : QWidget(overlay->parentWidget())
    , d(new DockOverlayCrossPrivate(this))
{
    d->m_dockOverlay = overlay;
#if defined(Q_OS_LINUX)
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
                   | Qt::X11BypassWindowManagerHint);
#else
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
#endif
    setWindowTitle("DockOverlayCross");
    setAttribute(Qt::WA_TranslucentBackground);
    d->m_gridLayout = new QGridLayout();
    d->m_gridLayout->setSpacing(0);
    setLayout(d->m_gridLayout);
}

DockOverlayCross::~DockOverlayCross()
{
    delete d;
}

void DockOverlayCross::setupOverlayCross(DockOverlay::Mode mode)
{
    d->m_mode = mode;
    QHash<DockWidgetArea, QWidget *> areaWidgets;
    areaWidgets.insert(TopDockWidgetArea, d->createDropIndicatorWidget(TopDockWidgetArea, mode));
    areaWidgets.insert(RightDockWidgetArea, d->createDropIndicatorWidget(RightDockWidgetArea, mode));
    areaWidgets.insert(BottomDockWidgetArea, d->createDropIndicatorWidget(BottomDockWidgetArea, mode));
    areaWidgets.insert(LeftDockWidgetArea, d->createDropIndicatorWidget(LeftDockWidgetArea, mode));
    areaWidgets.insert(CenterDockWidgetArea, d->createDropIndicatorWidget(CenterDockWidgetArea, mode));
    d->m_lastDevicePixelRatio = devicePixelRatioF();
    setAreaWidgets(areaWidgets);
    d->m_updateRequired = false;
}

void DockOverlayCross::updateOverlayIcons()
{
    if (windowHandle()->devicePixelRatio() == d->m_lastDevicePixelRatio) { // TODO
        return;
    }

    for (auto widget : qAsConst(d->m_dropIndicatorWidgets)) {
        d->updateDropIndicatorIcon(widget);
    }

    d->m_lastDevicePixelRatio = devicePixelRatioF();
}

void DockOverlayCross::setIconColor(ColorRole role, const QColor &color)
{
    d->m_iconColors[role] = color;
    d->m_updateRequired = true;
}

QColor DockOverlayCross::iconColor(ColorRole role) const
{
    return d->m_iconColors[role];
}

void DockOverlayCross::setAreaWidgets(const QHash<DockWidgetArea, QWidget *> &widgets)
{
    // Delete old widgets.
    const auto values = d->m_dropIndicatorWidgets.values();
    for (auto widget : values) {
        d->m_gridLayout->removeWidget(widget);
        delete widget;
    }

    d->m_dropIndicatorWidgets.clear();
    // Insert new widgets into grid.
    d->m_dropIndicatorWidgets = widgets;
    const QHash<DockWidgetArea, QWidget *> areas = d->m_dropIndicatorWidgets;
    QHash<DockWidgetArea, QWidget *>::const_iterator constIt;

    for (constIt = areas.begin(); constIt != areas.end(); ++constIt) {
        const DockWidgetArea area = constIt.key();
        QWidget *widget = constIt.value();
        const QPoint position = d->areaGridPosition(area);
        d->m_gridLayout->addWidget(widget, position.x(), position.y(), areaAlignment(area));
    }

    if (d->m_mode == DockOverlay::ModePannelOverlay) {
        d->m_gridLayout->setContentsMargins(0, 0, 0, 0);
        d->m_gridLayout->setRowStretch(0, 1);
        d->m_gridLayout->setRowStretch(1, 0);
        d->m_gridLayout->setRowStretch(2, 0);
        d->m_gridLayout->setRowStretch(3, 0);
        d->m_gridLayout->setRowStretch(4, 1);
        d->m_gridLayout->setColumnStretch(0, 1);
        d->m_gridLayout->setColumnStretch(1, 0);
        d->m_gridLayout->setColumnStretch(2, 0);
        d->m_gridLayout->setColumnStretch(3, 0);
        d->m_gridLayout->setColumnStretch(4, 1);
    } else {
        d->m_gridLayout->setContentsMargins(4, 4, 4, 4);
        d->m_gridLayout->setRowStretch(0, 0);
        d->m_gridLayout->setRowStretch(1, 1);
        d->m_gridLayout->setRowStretch(2, 1);
        d->m_gridLayout->setRowStretch(3, 1);
        d->m_gridLayout->setRowStretch(4, 0);
        d->m_gridLayout->setColumnStretch(0, 0);
        d->m_gridLayout->setColumnStretch(1, 1);
        d->m_gridLayout->setColumnStretch(2, 1);
        d->m_gridLayout->setColumnStretch(3, 1);
        d->m_gridLayout->setColumnStretch(4, 0);
    }

    reset();
}

DockWidgetArea DockOverlayCross::cursorLocation() const
{
    const QPoint position = mapFromGlobal(QCursor::pos());

    const QHash<DockWidgetArea, QWidget *> areas = d->m_dropIndicatorWidgets;
    QHash<DockWidgetArea, QWidget *>::const_iterator constIt;
    for (constIt = areas.begin(); constIt != areas.end(); ++constIt) {
        if (d->m_dockOverlay->allowedAreas().testFlag(constIt.key()) && constIt.value()
                && constIt.value()->isVisible() && constIt.value()->geometry().contains(position)) {
            return constIt.key();
        }
    }

    return InvalidDockWidgetArea;
}

void DockOverlayCross::updatePosition()
{
    resize(d->m_dockOverlay->size());
    QPoint topLeft = d->m_dockOverlay->pos();
    QPoint offest((this->width() - d->m_dockOverlay->width()) / 2,
                  (this->height() - d->m_dockOverlay->height()) / 2);
    QPoint crossTopLeft = topLeft - offest;
    move(crossTopLeft);
}

void DockOverlayCross::reset()
{
    const QList<DockWidgetArea> allAreas {
        TopDockWidgetArea,
        RightDockWidgetArea,
        BottomDockWidgetArea,
        LeftDockWidgetArea,
        CenterDockWidgetArea
    };
    const DockWidgetAreas allowedAreas = d->m_dockOverlay->allowedAreas();

    // Update visibility of area widgets based on allowedAreas.
    for (auto area : qAsConst(allAreas)) {
        const QPoint position = d->areaGridPosition(area);
        QLayoutItem *item = d->m_gridLayout->itemAtPosition(position.x(), position.y());
        QWidget *widget = nullptr;
        if (item && ((widget = item->widget()) != nullptr)) {
            widget->setVisible(allowedAreas.testFlag(area));
        }
    }
}

void DockOverlayCross::setIconColors(const QString &colors)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
    constexpr QString::SplitBehavior SkipEmptyParts = QString::SkipEmptyParts;
#else
    constexpr Qt::SplitBehaviorFlags SkipEmptyParts = Qt::SkipEmptyParts;
#endif
    static const QMap<QString, int> colorCompenentStringMap {
        {"Border", DockOverlayCross::Border},
        {"Window", DockOverlayCross::Window},
        {"Overlay", DockOverlayCross::Overlay},
        {"Arrow", DockOverlayCross::Arrow},
        {"Shadow", DockOverlayCross::Shadow}
    };
    auto colorList = colors.split(' ', SkipEmptyParts);
    for (const auto & colorListEntry : qAsConst(colorList)) {
        auto componentColor = colorListEntry.split('=', SkipEmptyParts);
        int component = colorCompenentStringMap.value(componentColor[0], -1);
        if (component < 0) {
            continue;
        }
        d->m_iconColors[component] = QColor(componentColor[1]);
    }

    d->m_updateRequired = true;
}

QString DockOverlayCross::iconColors() const
{
    return QString();
}

void DockOverlayCross::showEvent(QShowEvent *)
{
    if (d->m_updateRequired) {
        setupOverlayCross(d->m_mode);
    }

    this->updatePosition();
}

QADS_END_NAMESPACE
